package com.me.study.javaCore.agent;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.instrument.ClassFileTransformer;
import java.security.ProtectionDomain;

/**
 * Java Agent 技术：
 * 通过 ClassFileTransformer 提供的扩展点，使用 javassist 修改字节码。返回 null 表示不修改字节码，JVM 会继续加载原始的字节码（即 classFileBuffer 参数中传递的字节数组）
 *
 * @author ME
 */
public class MyTransformer implements ClassFileTransformer {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyTransformer.class);

    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classFileBuffer) {
        // TODO 返回 null 表示没有修改，JVM 会直接加载入参中的 classFileBuffer
        if (!"com/me/study/javaCore/agent/TransformTarget".equals(className)) {
            return null;
        }

        System.out.println("ClassLoader：" + loader);
        System.out.println("className：" + className);
        System.out.println("classBeingRedefined：" + classBeingRedefined);
        System.out.println("protectionDomain：\n" + protectionDomain);

        try {
            System.out.println("TestTransformer，当前类名:" + className);
            ClassPool classPool = ClassPool.getDefault();
            CtClass ctClass = classPool.get("com.me.study.javaCore.agent.TransformTarget");

            if (ctClass.isFrozen()) {
                LOGGER.info("isFrozen: {}", true);
                // ctClass.defrost();
                return ctClass.toBytecode();
            }

            CtMethod ctMethod = ctClass.getDeclaredMethod("print");
            ctMethod.insertBefore("{ System.out.println(\"start\");}");
            ctMethod.insertAfter("{ System.out.println(\"end\\\n\"); }");
            return ctClass.toBytecode();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new byte[0];
    }

}
